/**
 * Created by 白雨浓 on 2019/1/11 17:23.
 */
import { base } from "./java-reserved";

const ast = {};

const handleAst = (lines) => {

  lines = findClassContent(lines);

  if (!lines.length) {
    throw '内容为空';
  }

  findClassInfo(lines[0]);
  findFields(lines);
};

const toJSON = () => {
  let temp = `const ${ast.className} = {\n`;

  ast.fields.forEach(item => {
    const value = item.type.indexOf('List') >= 0 || item.type.indexOf('Set') >= 0 ? '[]' : 'null';

    let defaultValue = '';
    if (item.defaultValue) {
      defaultValue += ' 默认:' + item.defaultValue;
    }

    if (item.annotation) {
      temp += '    ' + `${item.name}: ${value}, /*${item.annotation} ${item.type}${defaultValue}*/\n`
    } else {
      temp += '    ' + `${item.name}: ${value},\n`
    }
  });

  temp += '}';
  console.log(temp);
  return temp;
};

/**
 * 寻找主体对象内容
 */
const findClassContent = (lines) => {

  let left = 0;
  let startLine = 0, endLine = lines.length;

  lines.forEach((line, index) => {

    if (line.indexOf('{') >= 0) {
      left++;

      if (!startLine) {
        startLine = index;
      }
    }

    if (line.indexOf('}') >= 0) {
      left--;

      if (left < 0) {
        throw '语法错误';
      }

      if (!endLine && left === 0) {
        endLine = index;
      }
    }
  });

  return lines.splice(startLine, endLine + 1);
};

/**
 * 寻找类信息
 */
const findClassInfo = (line) => {

  const items = line.split(' ');

  items.forEach((item, index) => {
    item = item.trim();

    if (item === base.class) {
      ast.className = items[index + 1].trim();
    }

    if (item === base.extends) {
      ast.extends = items[index + 1].trim();
    }

    if (item === base.implements) {
      const classes = line.split(base.implements)[1].trim();
      ast.implements = classes.substring(0, classes.length);
    }
  })

};

/**
 * 寻找属性
 */
const findFields = (lines) => {
  const fields = [];

  lines.forEach((line, index) => {
    if (line.indexOf(base.private) < 0) {
      return;
    }

    let code = line.split(';')[0];
    let annotation = line.split(';')[1];

    let defaultValue;
    if (code.indexOf('=') >= 0) {
      defaultValue = code.split('=')[1].trim();
      code = code.split('=')[0].trim();
    }

    const items = code.split(' ');

    if (items.length !== 3) {
      return;
    }

    let point = index;
    let over = false;
    if (point >= 0) {
      let last = lines[--point];
      let as = [];
      while (last && last.indexOf(base.private) < 0) {
        as.unshift(lines[point].trim());
        last = lines[--point];
      }

      let text = '';
      as = as.splice(as.indexOf('/**') + 1, as.indexOf('*/') - 1);

      as.forEach((item) => {
        text += item.replace('*', '').trim() + ' ';
      });

      if (text.trim().length !== 0) {
        over = true;
        annotation = text.trim();
      }
    }

    if (!over) {
      if (/\/\*.*\*\//.test(annotation)) {
        annotation = annotation.substring(annotation.indexOf('/*') + 2, annotation.indexOf('*/'));
      } else if (annotation.indexOf('//') >= 0) {
        annotation = annotation.substring(annotation.indexOf('//') + 2);
      }
    }

    if (annotation === line.split(';')[1]) {
      annotation = undefined;
    }

    const field = {
      type: items[1],
      name: items[2],
      annotation,
      defaultValue
    };


    fields.push(field)
  });

  ast.fields = fields;
};

export default (entity) => {

  const lines = entity.split('\n')
    .filter(line => line && line.trim().length)
    .map(line => line.trim());

  handleAst(lines);

  return toJSON();
}
